package ru.spb.osll.myfit.server.services;

import static ru.spb.osll.myfit.server.parser.PageUtils.getFullPathToContent;
import static ru.spb.osll.myfit.server.parser.PageUtils.getMetadataPath;

import java.io.File;
import java.io.IOException;
import java.net.URLClassLoader;
import java.util.Map;

import org.apache.log4j.Logger;

import ru.spb.osll.myfit.client.service.FitService;
import ru.spb.osll.myfit.common.Page;
import ru.spb.osll.myfit.common.VerificationResult;
import ru.spb.osll.myfit.common.TextParsingTools;
import ru.spb.osll.myfit.server.Configurator;
import ru.spb.osll.myfit.server.ImportsPrinter;
import ru.spb.osll.myfit.server.MyFitClassLoaderFactory;
import ru.spb.osll.myfit.server.fixtureiterator.FileFactory;
import ru.spb.osll.myfit.server.handler.ContentCreator;
import ru.spb.osll.myfit.server.handler.ContentHandler;
import ru.spb.osll.myfit.server.handler.Handler;
import ru.spb.osll.myfit.server.handler.PageLoader;
import ru.spb.osll.myfit.server.handler.ParentVariablesCreator;
import ru.spb.osll.myfit.server.handler.WikiPageWriter;
import ru.spb.osll.myfit.server.parser.TableUtils;
import ru.spb.osll.myfit.server.templateloader.JarTableTemplateLoader;
import ru.spb.osll.myfit.wikiverifier.WikiVerifierPageMarker;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 * 
 * @author kua
 */

@SuppressWarnings("serial")
public class FitServiceImpl extends RemoteServiceServlet implements FitService {
  private Handler m_contentHandler;
  private WikiPageWriter m_pageWriter;
  private Configurator m_configurator;
  private static Logger LOG = Logger.getLogger(FitServiceImpl.class);
  private WikiVerifierPageMarker m_pageWikiVerifier;
  public FitServiceImpl() {

    LOG.info("FitServiceImpl constructor");
    m_configurator = Configurator.getInstance();
    initialize();
  }

  private synchronized void initialize() {
    URLClassLoader m_classLoader = new MyFitClassLoaderFactory(
    new FileFactory()).createClassLoader(m_configurator.getDependenciesDir(),
    m_configurator.getFixtureDir());
    JarTableTemplateLoader templateLoader = new JarTableTemplateLoader(
    m_configurator.getFixtureDir(), m_classLoader);
    Map<String, Class<?>> m_fixtureClasses = templateLoader.getFixtureClasses();
    PageLoader pageLoader = new PageLoader(new TableUtils(m_fixtureClasses));
    ImportsPrinter m_importsPrinter = new ImportsPrinter(m_fixtureClasses, m_configurator);
    m_contentHandler = new ContentHandler(m_configurator.getRootDir(),
    pageLoader, new ContentCreator(), new ParentVariablesCreator(pageLoader));
    m_pageWriter = new WikiPageWriter(m_importsPrinter);
    m_pageWikiVerifier = new WikiVerifierPageMarker(templateLoader);
  }

  @Override
  public VerificationResult loadPage(String path) {
    Page page = m_contentHandler.loadPage(path);
    return verifyPage(page);
    //return page;
  }

  @Override
  public Page loadPageFromTestResultsDirectory(String pagePath, String pageId) {
    String rootName = new File(m_configurator.getRootDir()).getName();
    String testResultsDirectory = m_configurator.getTestResultsDirectory();
    String directory = testResultsDirectory + File.separator + pageId +
        File.separator + rootName;
    return m_contentHandler.loadPageFromDirectory(pagePath, directory);
  }

  @Override
  public Page loadPageFromSuiteResultsDirectory(String pagePath, String suiteResultId) {
    String rootName = new File(m_configurator.getRootDir()).getName();
    String suiteResultsDirectory = m_configurator.getSuiteResultsDirectory();
    String directory = suiteResultsDirectory + File.separator + suiteResultId +
            File.separator + rootName;
    return m_contentHandler.loadPageFromDirectory(pagePath, directory);
  }

  @Override
  public void savePage(String path, Page page) {
    try {
      LOG.debug("run savePage");
      m_pageWriter.savePage(getFullPathToContent(m_configurator.getRootDir(), path), page);
      m_pageWriter.saveMetadata(getMetadataPath(m_configurator.getRootDir(), path), page);
      LOG.info("save page: " + path);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Override
  public String getPagePath() {
    LOG.debug("try get attrib \"pagePath\" ");
    String pagePath = (String) getServletContext().getAttribute(
        TextParsingTools.PAGE_PATH_ATTRIBUTE);
    LOG.debug("attrib \"pagePath\" = " + pagePath);
    getServletContext().removeAttribute(TextParsingTools.PAGE_PATH_ATTRIBUTE);

    return pagePath;
  }
  
  @Override
   public VerificationResult verifyPage(Page page){
     return m_pageWikiVerifier.verifyPage(page);
     //return page;
   }
  
  @Override
  public void reloadTemplates() {
	  initialize();
  }
}
